package com.interview.com.aop.User.proxy;

import com.interview.com.aop.User.UserManager;
import com.interview.com.aop.User.UserManagerImpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Created by fangjicai on 2020/4/23.
 */
public class JdkProxy implements InvocationHandler {
    private Object target ;//需要代理的目标对象


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("JDK动态代理，监听开始！");
        Object result = method.invoke(target, args);
        System.out.println("JDK动态代理，监听结束！");
        return result;
    }

    //定义获取代理对象方法
    private Object getJDKProxy(Object targetObject){
        //为目标对象target赋值
        this.target = targetObject;
        //JDK动态代理只能针对实现了接口的类进行代理，newProxyInstance 函数所需参数就可看出  看出jdk动态代理必须有默认接口，否则
        //jdk动态代理失效
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
    }

    public static void main(String[] args) {
        JdkProxy jdkProxy = new JdkProxy();//实例化JDKProxy对象
        UserManager target=new UserManagerImpl();
        System.out.println("方法没有增强之前");
        target.delUser("fangjicai");
        UserManager user = (UserManager) jdkProxy.getJDKProxy(target);//获取代理对象
        user.delUser("fangjicai");;//执行新增方法
    }
}

//spring aop是通过动态代理实现的，有两种方式
//1.jdk 动态代理  核心包含：InvocationHandler  Proxy ，思路： 通过实现InvocationHandler接口，重写invoke方法，
//实现目标代理对象方法的增强，同时通过Proxy的newProxyInstance获取目标代理对象，入参包含代理目标对象的
//类加载器、实现的接口、this,可以看出jdk动态代理必须目标类有实现的接口才行，否则无法完成jdk动态代理

//2.cglib 思路：动态生成目标对象的子类（动态继承目标对象，并重写目标对象的方法，实现方法的增强）
//       //xxx 增强代码
//        //super.addUer()
//        //xxxxx  增强代码

//局限性：加入目标对象被final修饰的话，无法完成方法的增强！！
